"""
135.分发糖果
https://leetcode-cn.com/problems/candy

老师想给孩子们分发糖果，有 N 个孩子站成了一条直线，老师会根据每个孩子的表现，预先给他们评分。

你需要按照以下要求，帮助老师给这些孩子分发糖果：

每个孩子至少分配到 1 个糖果。
评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
那么这样下来，老师至少需要准备多少颗糖果呢？

示例1:
输入：[1,0,2]
输出：5
解释：你可以分别给这三个孩子分发 2、1、2 颗糖果。

示例2:
输入：[1,2,2,2]
输出：5
解释：你可以分别给这三个孩子分发 1、2、1、1 颗糖果。
     第三个与第四个孩子均只得到 1 颗糖果，这已满足上述两个条件。

提示:
N >= 1
"""
class Solution:
  """
  遍历 ratings 以分配糖果，每次尽可以少分配，则分配第 i 个孩子糖果时:
    如果 ratings[i] > ratings[i - 1], 则分配 上次分配数 + 1 个糖果
    如果 ratings[i] == ratings[i - 1]，则分配 1 个糖果
    如果 ratings[i] < ratings[i - 1], 则分配 1 个糖果，但:
      设单调减序列尾长度为 n, 序列头(只有 1 个孩子)分配数为 m,
      如果 n + 1 < m，则需要给序列尾中的每个孩子多分配 1 个糖果，还需要多分配 n 个糖果，n += 1
      否则，需要给序列尾的每个孩子及序列头多分配 1 个糖果，还需要多分配 n + 1 个糖果，n += 1
  """
  def candy(self, ratings: list[int]) -> int:
    r = 1  # 总分配数
    p = 1  # 上个孩子的分配数
    h = 1  # 单调减序列头分配数
    t = 0  # 单调减序列尾长度
    x = ratings[0]  # 前面孩子的评分
    for i in ratings[1:]:
      if i > x:
        r += (p + 1)
        p += 1
        h = p
        t = 0
      elif i == x:
        r += 1
        p = 1
        h = 1
        t = 0
      else:
        if t + 1 < h:
          r += (t + 1)
        else:
          r += (t + 2)
        p = 1
        t += 1
      x = i
    return r
